home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / Jim's CDEFs v1.30 / Documents / About CDEF's next >
Encoding:
Text File  |  1994-11-06  |  62.7 KB  |  1,555 lines  |  [TEXT/KAHL]

  1. Jim's CDEFs  - Copyright © 1994 by James G. Stout
  2. --------------------------------------------------------------------------------
  3. About Jims CDEFs…
  4.  
  5. If you have downloaded previous versions of this package, please read the 
  6. revision history at the bottom of this file, some minor but important 
  7. details have changed !!
  8.  
  9. Also, please read the license agreement in the "Conditions for use…"
  10. document included with the package.
  11.  
  12. This is a collection of 10 CDEFs (Control Definitions) some bits of
  13. source code to demo their use AND the source code for all of the CDEFs.
  14.  
  15. (If you are new to Mac programming, CDEFs are code resources that can just
  16. be pasted into your project's resource file and used by your programs).
  17.  
  18. Jim Stout
  19.  
  20. November 1994
  21.  
  22. I can be reached electronically at:
  23.  
  24. Internet    : JimS@WRQ.COM    (work hours, PST)
  25. AppleLink   : WRQ            (daily)
  26. CompuServe  : 73240,2052    (weekly or so)
  27. AOL         : JasG            (weekly or so)
  28. eWorld      : Jim Stout        (weekly or so)
  29. --------------------------------------------------------------------------------
  30.  
  31. The CDEFs or other code in this package may be incorporated in any freeware, 
  32. shareware, commercial or other software package, subject to the conditions in
  33. the "License for Use" that accompanies this package.
  34.  
  35. --------------------------------------------------------------------------------
  36.  
  37. The CDEFs in this package are:
  38.  
  39. procID    Name            Function
  40. ------    -----------        --------------------------------------------------------
  41. 100        GroupBox        Titled box, text in upperleft
  42. 101        PopUp Menu        System 7 style popup menu control for System 6 or 7
  43. 102        Spinner            A "little arrows" control
  44. 103        Date & Time        Date & Time control using "little arrows"
  45. 104        Tog Button        New type of "one or many" control
  46. 105        HSlider            Horizontal slider control
  47. 106        VSlider            Vertical slider control
  48. 107*    3D Buttons        3d replacement for the standard button CDEF
  49. 108        Progress Bar    A "thermometer" or "barber pole" progress indicator
  50. 109        TabPanel        A "Tab Panel" control as in MSWord
  51.  
  52. * this CDEF has been renumbered to 0 in the xDEF.rsrc file
  53. --------------------------------------------------------------------------------
  54.  
  55. The source code for all of the CDEFs is included, and you can find
  56. the CDEFs as code resources in file xDEF.rsrc.  The cdefXXX π projects are
  57. Think C 6.01, but should convert to 7.04 with no problems.
  58.  
  59. A set of standard #defines for variation codes etc. is provided in file
  60. "jimsCDEF.h".
  61.  
  62. I have not built these on a Power Mac yet…
  63.  
  64. Also included is source for utility routines common to all of the CDEFs.  
  65. A test harness to allow source level debugging is also included.  Rather
  66. than take up the room for 10 test projects and code, there is only one - for
  67. the 3D Button CDEF.  Test projects for the other 9 is left to the reader as
  68. a programming exercise.
  69.  
  70. --------------------------------------------------------------------------------
  71. This file is getting pretty long, it is divided into the following sections:
  72.  
  73.     - Introduction
  74.     - Control Descriptions
  75.     
  76. CDEF details
  77.     - Variation codes & control size 
  78.     - Non-standard control RefCon usage
  79.     - Non-standard control template usage
  80.     
  81. General information
  82.     - Using custom controls in a dialog
  83.     - Using custom controls in a window
  84.     - Colorizing Controls & Dialogs
  85.     - Changing the font in a Dialog
  86.     
  87.     - Special popup menu notes
  88.     - About "TogButtons" 
  89.     - About Tab Panels
  90.     - Revision history
  91.  
  92. --------------------------------------------------------------------------------
  93. Introduction
  94. ============
  95.  
  96. A few months back I was reading the Human Interface volume of Inside Mac and it
  97. struck me as funny that Apple refers to various controls (used throughout the
  98. MacOS) as "not supported by the Toolbox".  Controls like "little arrow"
  99. controls used to set Date & Time, Memory etc., "Slider  Controls" like those in
  100. the Sound or Brightness control panels and a "Progress Bar" are simply are not
  101. to be found in the Toolbox.
  102.  
  103. Apple simulates controls by displaying appropriate PICT's and handling mouse
  104. events in a dialog filter (I think).
  105.  
  106. I realized that over the past couple of years, I had written some of those
  107. controls (the rest are hot off my coding pad).
  108.  
  109. Two of the CDEFs, 104 "Tog Button" and 109 "TabPanel" are a little different. 
  110. This is explained below in the sections "About Tog Buttons" and "About Tab 
  111. Panels.
  112.  
  113. All of these controls will work with System 6 or System 7 - the only caveats
  114. are:
  115.  
  116.     - PopUpMenu control requires PopUpMenuSelect.  
  117.     - TabPanel control requires AppendDITL etc. (System 6 with CTB or System 7)
  118.     - 32bit ColorQuickdraw v1.2 is required for any of the controls to draw
  119.       "3D" variants and to use the System 7 style gray when disabled.
  120.           
  121. I have tested them on machines from a MacPlus through a Power Mac 7100.
  122. (Actually, I've tested these as far back as System 3.2 - I've gotta do
  123. something with that original 128k Mac with MacPlus ROM's that  is sitting in
  124. the corner...)
  125.  
  126. All controls with titles honor the "useWindFont" variation code (to draw in a
  127. non-System font) and if possible, the controls will honor control colors found
  128. in 'cctb' resources.
  129.  
  130. The "3D Buttons" and "TabPanel" CDEFs will always use a "3D" effect if the
  131. background color is non-white AND the control can draw itself in color. 
  132. This behavior cannot be overridden for these controls.  Sorry.
  133.  
  134. As far as I can tell, the controls all handle low memory situations by 
  135. refusing to draw themselves.  Let me know if you see any problems.
  136.  
  137. I have not written these to support non-roman script systems.
  138.  
  139. Other variation codes, sizes and non-standard control template values are
  140. listed below.
  141.  
  142. --------------------------------------------------------------------------------
  143. Control Descriptions
  144. ====================
  145.  
  146. Common features:
  147.  
  148.     - color per 'cctb' resources.
  149.     - disable with "GrayishTextOr" effect under System 7.
  150.     - have an embossed, 3D variation.
  151.     - respect the "useWindFont" variation code (8).
  152.     - All control drawing is clipped to the control rect, so it should be
  153.       pretty obvious if you have a control rect that is too small.
  154.     
  155.     NOTE: all of these controls rely on a private data structure stored in
  156.           the contrlData field of the control structure.  Don't
  157.           use this field for your own use or unpredictable things
  158.           will happen.
  159.           
  160.           Also, some of the controls look at the value of the refCon when
  161.           initializing to get some extra parameters.
  162.           
  163.           If you want to place a value in the refCon for your program's use, 
  164.           don't set it until AFTER you call NewControl or NewDialog and
  165.           the controls have been initialized. (The DateTime CDEF is a MAJOR
  166.           exception - see below - it uses the refCon for its "value" field.)
  167.             
  168. --------------------------------------------------------------------------------
  169. GroupBox
  170.  
  171.     This control is pretty simple. It frames the control rect and places
  172.     the title in the upper left corner.
  173.     
  174.     It can be used to logically group a series of related controls.
  175.     
  176.     It does not respond to mouse clicks, it does have variation
  177.     codes for a dashed-line frame and a 3D effect.
  178.     
  179.     To use this control, you have to play some games with the control
  180.     rect to keep it from overlaying other controls.  Essentially, you
  181.     must set the control rect height to include ONLY the title and then
  182.     specify the true height of the control in the contrlMax field.
  183.     
  184.     In response to an update event, you will need to call DrawControls or 
  185.     Draw1Control for this control. 
  186.     
  187.     UpdtControls WILL NOT WORK !!!!
  188.     
  189. --------------------------------------------------------------------------------
  190. PopUp Menu
  191.  
  192.     This control was written to replace both the System 6 & 7 versions of
  193.     the Apple CDEF 63.  
  194.     
  195.     Apple's CDEF has some problems - it behaves  differently under System 6 
  196.     and System 7.  The System 6 version does not honor menus with icons,
  197.     requires a special variation code for color menus and has problems with
  198.     menus narrower than the control rect (when using the popupFixedWidth
  199.     variation code).  
  200.     
  201.     The System 7 version does not draw colored menus at all.
  202.     
  203.     Neither version will work with a dynamically created menu.
  204.  
  205.     You should be able to use this CDEF with the same parameters as the
  206.     Apple CDEF.
  207.     
  208.     There are several enhancements explained in the section on Non-standard
  209.     control template usage and in the "Special popup menu notes" section.
  210.     
  211.     The handle stored in the contrlData field is as documented by Apple
  212.     and can be used to retrieve the MenuHandle of the popup menu.  See
  213.     IM VI and the jimsCDEF.h file.
  214.     
  215. --------------------------------------------------------------------------------
  216. Spinner
  217.  
  218.     This a control that "Apple never wrote".  It allows for adjustment of
  219.     a numeric value via "little" arrows.  The arrows can be vertical or
  220.     horizontal.
  221.     
  222.     The default increment is 1, but this can be specified in the control
  223.     template in the refCon field.  The control value will increment in
  224.     a "ballistic" manner - as the mouse button is held down, the increment
  225.     value will increase from 1 to 10 to 100 to 1000.
  226.     
  227.     This CDEF can be "linked" to a dialog edit text item to update.
  228.     
  229.     CDEFs cannot get keyDown events, so the trick here is to have the
  230.     CDEF update the edit text item.  To do this, set the HiWord of
  231.     control refCon to a DITL editText item number to be updated.  In
  232.     this case, set the LoWord of the refCon to the desired increment.
  233.     
  234.     The calling program must take care of insuring that only digits
  235.     are typed into the edit text. ALSO, when the user types new
  236.     digits, the calling program must get the contents of the edit item,
  237.     convert it to a number and call SetCtlValue to let the control
  238.     know about the new value.  Otherwise, the next click in the 
  239.     control will wipe out the typed value.
  240.     
  241.     The handle stored in the contrlData field is documented in the
  242.     jimsCDEF.h file.  There is a "userData" field for your use.
  243.     
  244.     PartCodes returned via TrackControl are :
  245.         2 - in up arrow
  246.         3 - in down arrow
  247.         
  248.     (the control will have updated its value when TrackControl returns)
  249.     
  250. --------------------------------------------------------------------------------
  251. Date & Time
  252.  
  253.     This is a control to adjust Date and/or Time values.  Clicking on
  254.     a time or date component (month, hours, etc.) will highlight 
  255.     those digits and show "little" arrows that can be used to adjust 
  256.     the date or time value.
  257.     
  258.     Variation codes can specify display of Date, Time, both, horizontal 
  259.     or vertical display.  The m/d/y order of the date will match what 
  260.     the user has set in the Date & Time control panel.  Leading zeros
  261.     are always drawn - it makes things a lot simpler for the CDEF.
  262.     
  263.     Likewise, 12 or 24 hour time is taken from the system settings. To
  264.     force a 24 hour setting, pass a non-zero contrlMax in the control 
  265.     template. To get a "3D" effect for the control title and arrows, 
  266.     pass a non-zero contrlMin in the control template.
  267.     
  268.     The "value" of the control is a DateTimeRec.  Since this is a long,
  269.     it is stored in the contrlRfCon field, NOT in the contrlValue field
  270.     of the control record. So, rather than using GetCtlValue(), use
  271.     GetCRefCon() to access the control value.
  272.     
  273.     There is no keyboard handling for setting date & time.  CDEFs do
  274.     not have any mechanism for keyboard events.  I think that this could
  275.     be done from a user program, but I'll leave that as an exercise for
  276.     those that need it. 
  277.     
  278.     (Hint, the contrlValue is always the highlighted digits field and you can 
  279.     change the date & time shown by the control    by setting a new DateTimeRec 
  280.     into the control RefCon and drawing the    control.)
  281.     
  282.     Resetting the date and time requires the following:
  283.     
  284.                 GetDateTime(&secs);
  285.                 SetCRefCon(hCtrl, secs);
  286.                 InvalRect(&(**hCtrl).contrlRect);
  287.     
  288. --------------------------------------------------------------------------------
  289. Tog Button
  290.  
  291.     This is explained in great detail below.
  292.     
  293.     A "Tog" button is a diamond shaped control, a mix of CheckBox and
  294.     Radio button behavior.  A group of these controls can have many
  295.     "on" members (like a checkbox), but must always have one member
  296.     that is "on" (like a radio button).
  297.     
  298.     This file requires use of some support routines in TogLib.c that
  299.     must be called by your program.
  300.     
  301.     Variation code 4 in the 3D Buttons control will have the same
  302.     result.
  303.     
  304. --------------------------------------------------------------------------------
  305. HSlider
  306.  
  307.     This is an exact duplicate of the slider control in the Brightness
  308.     Control Panel.
  309.     
  310.     Several variation codes are available to alter the appearance of
  311.     the control.  See below or the demo program.
  312.     
  313.     This and the VSlider control will call back to an "actionProc" if
  314.     one is set via SetCtlAction() and you call TrackControl with -1 as
  315.     the last parameter.  This could be used to implement a "live" 
  316.     display of the control value as the thumb is dragged around.
  317.     
  318.     Part codes returned to TrackControl are :
  319.         1 - in "thumb"
  320.         2 - in "decrease"
  321.         3 - in "increase"
  322.  
  323. --------------------------------------------------------------------------------
  324. VSlider
  325.  
  326.     This is an exact duplicate of the slider control in the Sound
  327.     Control Panel.
  328.  
  329.     Several variation codes are available to alter the appearance and
  330.     behavior of the control.  See below or the demo program.
  331.     
  332.     See notes above for "actionProc" & TrackControl issues.
  333.     
  334. --------------------------------------------------------------------------------
  335. 3D Buttons
  336.     
  337.     This is a pretty "bare bones" CDEF.
  338.     
  339.     I'm including it more as a simple example CDEF than as a serious  
  340.     replacement for the standard CDEF 0 (which supplies controls for check 
  341.      boxes, radio buttons, push buttons).  See develop issue 15 for a good 
  342.     article about "Working in the third dimension" and 3D controls.  
  343.     
  344.     An addition is variation code 4 - in this control it supplies a 
  345.     "Tog" button.
  346.     
  347.     It provides 3D equivalent to the standard controls.  The push
  348.     button variation is a square edged, raised button.  Text is
  349.     "embossed".  
  350.     
  351.     It looks best on a background with rbg values of 0xCCCC.
  352.     
  353. --------------------------------------------------------------------------------
  354. Progress Bar
  355.  
  356.     This is a control to provide a "thermometer" or "barber pole"
  357.     indicator. It can be used to display the progress of a long 
  358.     running operation (like the thermometer in the "Copying file…" 
  359.     alert.  The "barber pole" variation can be used when the
  360.     operation is proceeding, but the end point is not known - like
  361.     searching for a series of files.
  362.     
  363.     Variation codes can be used for horizontal, vertical, rectangular,
  364.     oval or barber pole indicators.
  365.     
  366. --------------------------------------------------------------------------------
  367. TabPanel
  368.     
  369.     This too, is explained in great detail below.
  370.     
  371.     This is a problematic control.  It will be too "Windows-like" for
  372.     many.  I wrote it to see if it could be done on the Mac after seeing
  373.     what a co-worker was doing.  Don't use it if you don't like it.
  374.     
  375.     It draws a box with a series of "tabs" long the top edge, like At Ease
  376.     in some respects.  It could be used to provide a dialog with multiple
  377.     "panels" - like the Think Project Manager "Options" dialog which uses
  378.     a popup to switch panels, or many CommToolbox tools which use a list
  379.     of icons. 
  380.     
  381.     By default, there are 4 tabs per row with a maximum of 5 rows of tabs.
  382.     This can be changed to get between 2 and 8 tabs/row.
  383.     
  384.     Clicking on a "tab" will change the control value. Your program can
  385.     then change the other controls on the panel - either by hiding/showing
  386.     controls or using ShortenDITL/AppendDITL calls.
  387.         
  388.     To use this control, you have to play some games with the control
  389.     rect to keep it from overlaying other controls.  Essentially, you
  390.     must set the control rect height to include ONLY the tab titles and
  391.     then specify the true height of the control in the contrlMin field.
  392.  
  393.     In response to an update event, you will need to call DrawControls or 
  394.     Draw1Control for this control. 
  395.     
  396.     UpdtControls WILL NOT WORK !!!!
  397. --------------------------------------------------------------------------------
  398. CDEF details
  399. --------------------------------------------------------------------------------
  400.  
  401. See file jimsCDEF.h for #defines for variation codes and structs for private
  402. data for Spinner & Popup menu CDEFs.
  403.  
  404. Variation codes & control size 
  405. ==============================    
  406.  
  407. (min h & w is minimum required height & width for the control rect 
  408. when using Chicago 12 font)
  409.  
  410. CDEF        varCode        min h & w    Result
  411. ---------    ----------    ----------    --------------------------------------------
  412. GroupBox    0            16 x nn        Draws a solid frame
  413.             1                        Draws a dotted frame
  414.             2                        3D effect on non-white backgrounds
  415.             4                        an "inset box" effect on non-white backgrounds
  416.             8                        Use the Window font for title
  417.             
  418.             NOTE: To avoid problems with "layering" of this control over or
  419.                   under the contents of a box, set the height of this control 
  420.                   to 16 or so, then put the height you REALLY want in the 
  421.                   contrlMax field of the CNTL template.  The control rect 
  422.                   (used by the Dialog Manager) will not obstruct other controls.
  423.                   However, when the control draws - it will use the height value
  424.                   from the contrlMax field.
  425.                   
  426.                   Uses cFrameColor & cTextColor from 'cctb'
  427.                   
  428. --------------------------------------------------------------------------------            
  429. PopUp Menu                19 x nn        (see IM VI or Docs for Apple CDEF 63
  430.                         19 x 25        for "triangle only" menu
  431.             1                        use fixed width for menu
  432.             2                        3D effect
  433.             4                        use refCon for AddResMenu
  434.             8                        Use the Window font for title & menu
  435.             
  436.             NOTE: if the menu has styled text items, the height may need to be 
  437.                   greater than 19.  It will need to be enlarged to if you have
  438.                   icons on the menu - make the height equal icon height + 5.
  439.                   
  440.                   Unlike the Apple CDEF 63, this control will:
  441.                     - behave the same with System 6 & 7
  442.                     - properly handle colored menus
  443.                     
  444.                   There are several enhancements, see below.
  445.                     
  446.                   Uses cTextColor for title and colors from 'mctb' for menu.
  447.                   
  448. --------------------------------------------------------------------------------    
  449.  
  450. Spinner        0            18 x nn        Small, as in "Date & Time" Control panel
  451.             1            25 x nn        Large, as in "Memory" Control panel
  452.             2                        3D arrows
  453.             4                        Horizontal arrows
  454.             8                        Use the Window font for drawing
  455.             
  456.             NOTE: use 18 x 11 or 25 x 15 to get arrows only.
  457.                   3D arrows are colored, as are system scroll bars, with
  458.                   with cTingeLight & cTingeDark.
  459.                   
  460. --------------------------------------------------------------------------------    
  461.  
  462. Date & Time    0            18 x 160    Date left, Time right justified    
  463.             1            18 x 80        Date only, left justified    
  464.             2            18 x 80        Time only, left justified    
  465.             4            37 x 80        Both on 2 lines, date over time
  466.             8                        Use the Window font for drawing
  467.                         
  468.             NOTE: non-standard date or time separator characters may   
  469.                   need a larger rect.  Also, if a title is specified,
  470.                   the width of the control will need to be increased.
  471.                   
  472.                   Uses cFrameColor & cTextColor.  3D arrows colored
  473.                   with cTingeLight & cTingeDark.
  474.                   
  475. --------------------------------------------------------------------------------    
  476.                                 
  477. Tog Button    0            18 x nn        Normal button title
  478.             1                        * not used *
  479.             2                        * not used *
  480.             4                        * not used *
  481.             8                        Use the Window font for title
  482.             
  483.                   Uses cFrameColor & cTextColor from 'cctb'
  484.                   
  485. --------------------------------------------------------------------------------    
  486.                         
  487. HSlider        0            24 x 121    As in the "Brightness" Control panel
  488.             1                        Scale drawn in bg color (not filled)
  489.             2                        Drawn with a 3D effect
  490.             4                        Scale drawn in gray pattern
  491.             8                        * not used *
  492.             
  493.                   Uses cFrameColor & cTextColor from 'cctb'
  494.                   
  495. --------------------------------------------------------------------------------    
  496.  
  497. VSlider        0            105 x 42    As in the "Sound" Control panel
  498.             1                        Scale drawn in bg color (not filled)
  499.             2                        Drawn with a 3D effect
  500.             4                        "Thumb" will not "snap" to tick mark
  501.             8                        Scale is blank, no numbers, no marks
  502.             
  503.             NOTE: ht is 12*divisions + 21 (see below)
  504.                   Uses cFrameColor & cTextColor from 'cctb'
  505.                   
  506. --------------------------------------------------------------------------------    
  507.  
  508. 3D Buttons    0            any x any    draws a push button
  509.             1                        draws a checkbox
  510.             2                        draws a radiobutton
  511.             4                        draws a Tog Button control
  512.             8                        Use the Window font for title
  513.             
  514.             NOTE: This control should behave just like the standard CDEF 0 when 
  515.                     running in 1 bit (B&W) mode OR if the background is white. If 
  516.                     running on a non-white background, this CDEF will draw "3 D" 
  517.                     controls.
  518.                     
  519.                   Uses cFrameColor & cTextColor from 'cctb'. Gray shading is a
  520.                   gray that is intermediate to the background color & cFrameColor.
  521.                   
  522. --------------------------------------------------------------------------------    
  523.  
  524. Progress Bar 0            any x any    draws a horizontal progress bar
  525.              1                        draws a vertical progress bar
  526.              2                        draws a rounded, 3D progress bar
  527.              4                        draws a "Barber Pole" progress bar
  528.              8                        not used
  529.              
  530.             NOTE: to get a "Barber Pole" variation to work, you need to call
  531.                     it with a different value each time.  Simply setting min=0
  532.                     and max=1, then setting its value to 0, then 1, then 0 etc.
  533.                     inside your loop operation will work.
  534.           
  535.                     'cctb' resource entries for cFillPat and cTingeLight are used
  536.                     to color this control.
  537.                     
  538. --------------------------------------------------------------------------------
  539.  
  540. TabPanel     0            20 x nn        tab label is Geneva 9, bold for active tab.
  541.              1                        Use System font for tab label, underline
  542.                                      for active tab.
  543.              2                        1 row of tabs, contrlMax columns.
  544.              4                        not used
  545.              8                        Use the Window font for tab label, bold
  546.                                      for active tab.
  547.     
  548.             NOTE: To avoid problems with "layering" of this control over or
  549.                   under the contents of a box, set the height of this control to
  550.                   16 * rows, then put the height you REALLY want in the contrlMin 
  551.                   field of the CNTL template.  The control rect (used by the 
  552.                   Dialog Manager) will not obstruct other controls.  However, 
  553.                   when the control draws - it will use the height value from the 
  554.                   contrlMin field.
  555.                   
  556.                   Uses cFrameColor & cTextColor from 'cctb'. Gray shading is a
  557.                   gray that is intermediate to the background color & cFrameColor.
  558.  
  559.                   The default of 4 tabs per row can be changed via the LoWord of
  560.                   the refCon to 2 - 8.  See below.
  561. --------------------------------------------------------------------------------    
  562.             
  563. Non-standard control refCon usage
  564. ===================================
  565.  
  566. Note:     Several of these controls use the control refCon field.  Strictly
  567.         speaking, the refCon should be left for the caller's use, not for
  568.         the CDEF.  But… the Apple CDEF broke the rule and I blithely 
  569.         followed along (sorry).  Except for the DatTime CDEF, the refCon is
  570.         used only at the time the CDEF intializes, and its value is used
  571.         to produce non-default behavior or appearance.  
  572.         
  573.         If you need the refCon change the appropriate init() routine for 
  574.         the CDEF.
  575.         
  576. PopUp Menu     - use of refCon is identical to Apple's CDEF 63
  577.  
  578.             - not used by control after initialization.
  579.                     
  580. Spinner        - refCon may be used to indicate an "increment" value.  Also,
  581.               you can set both an increment and a DITL item (for an edit
  582.               text item to update). See below.
  583.             - the increment value is limited to 1-1000 and the DITL item
  584.               number must be 0-100.
  585.               
  586.             - not used by control after initialization.
  587.                     
  588. VSlider     - refCon may be used to indicate the number of divisions 
  589.               but will default to 7 divisions.  Must be in the range
  590.               2-20.
  591.               
  592.             - not used by control after initialization.
  593.                     
  594. DateTime    - refCon is the "value" of the control.  It is updated
  595.               by the control.
  596.               
  597.             - ** USED ** by control after initialization - see below.
  598.                 
  599. Tab Panel    - LoWord of the refCon is "tabs per row" - from 2 to 8. If
  600.               outside this range, the default is 4 tabs per row.
  601.             - HiWord of the refCon is a "notch".  If non-zero, there will
  602.               be a notch in the the right corner with no tab, if zero,
  603.               tabs will fill the entire width of the control.  This value
  604.               must be between 0 and control width/2.
  605.               
  606.             - not used by control after initialization.
  607.                     
  608. --------------------------------------------------------------------------------
  609.  
  610. Non-standard control template usage
  611. ===================================
  612.  
  613. The Macintosh Control Manager is pretty limited in its capability for numerous
  614. control variants (just look at the popup menu CDEF!), allowing overlapping
  615. controls or passing special data to the control.
  616.  
  617. I attempted to make it possible to initialize all of these controls via standard
  618. 'CNTL' templates or calls to NewControl() rather than requiring the calling 
  619. program to make additional calls or use special data structures.  This approach
  620. means the the meanings of some template values have been redefined as listed
  621. below:
  622.  
  623. GroupBox        does not use min, value or refCon. max is used for the
  624.                 true height of the control.
  625.                 
  626.                 Rect should be 16 pixels high, just enough for the title.
  627.  
  628. PopUp Menu        (see Inside Mac VI or other Docs for Apple CDEF 63)
  629.                 
  630.                 Briefly:
  631.  
  632.                 procId    : 1616 + varCode  (101 * 16) + varCode
  633.                         : varCodes
  634.                             popupFixedWidth        = 0x0001
  635.                             ctl3D                = 0x0002
  636.                             popupUseAddResMenu    = 0x0004
  637.                             popupUseWFont        = 0x0008
  638.                             
  639.                 value    : Title justification
  640.                            :     popupTitleLeftJust        = 0x00000000
  641.                          :     popupTitleCenterJust    = 0x00000001
  642.                          :     popupTitleRightJust        = 0x000000FF
  643.                          
  644.                            There are also several values for setting text
  645.                            style for the popup title.  See Inside Mac.
  646.  
  647.                 min        : resId of menu to use, even if using 
  648.                           popupUseAddResMenu, it is best to have a 
  649.                           'dummy' menu resource with no items defined.
  650.  
  651.                 max        : width of title item - from controlRect.left  
  652.                         :  0 = no title drawn.
  653.                         
  654.                         Enhancements:
  655.                         
  656.                         The following are 7 "pseudo variation codes" that can
  657.                         be added to the max field (title width).
  658.                     
  659.                           popupNoMark      : Don't use a checkmark on current item.
  660.                           popupBlackSymbol: Always draw symbol in black.
  661.                           popupInsetFrame : Draws an inset 3D popup frame.
  662.                           
  663.                           popupSymbolOnly : Draw popup symbol for "type-in menus"
  664.                           popupNoSymbol      : Don't draw popup symbol at all.
  665.                           popupCenterText : Don't draw popup symbol, don't expand 
  666.                                               control width to that of the menu and
  667.                                               center item text in control rect.
  668.                           popupIconOnly      : Draw item Icon in a framed box.
  669.                           
  670.                         : use of these means that the title width must be less
  671.                           than 255 characters, but that seems to be a rather
  672.                           reasonable restriction.
  673.                           
  674.                         : popupNoMark, popupBlackSymbol and popupInsetFrame can 
  675.                           be combined with others, but combinations of the last 
  676.                           4 are undefined.
  677.  
  678.                 refCon    : if varCode of popupUseAddResMenu, put the 
  679.                           ResType in the refCon field of the control.
  680.  
  681. Spinner            standard use of min, max and value.
  682.                 
  683.                 The control refCon field can be set to a long word 
  684.                 that indicates both the increment to use and a DITL 
  685.                 item to    update (optional).
  686.                 
  687.                 LOWORD = increment value (default increment is 1)
  688.                 HIWORD = DITL item number for an editText item to 
  689.                          update with the control value.
  690.                         
  691. Date & Time        max - if non-zero, reverse 12/24 hour setting.
  692.                 min - if non-zero, draw "3D" control.
  693.                 
  694.                 contrlValue indicates highlighted digits
  695.                 1    hours
  696.                 2    minutes
  697.                 3    AM/PM
  698.                 7    month  (7,8,9 match user order from Control Panel
  699.                 8    day        and may not have these meanings)
  700.                 9    year
  701.                                     
  702.                 contrlRfCon is seconds as passed to GetDateTime(),  
  703.                 Secs2Date() and Date2Secs() calls.  This is the "value" 
  704.                 that the control adjusts.  Use GetCRefCon() to retrieve 
  705.                 the "date time" value and SetCRefCon() to set it.
  706.                         
  707. HSlider            min = 0, max = 100 - these are set by the control.
  708.  
  709.                 value returned will range from 0 to 100
  710.  
  711. VSlider            refCon is used to indicate 'number of divisions' from 
  712.                 2-20. Default is 7 divisions with tick marks from 0-7.
  713.                 min = 0
  714.                 max = 12*"number of divisions"
  715.                         
  716.                 The value returned will range from 0 to max.
  717.                         
  718.                 The control "thumb" will "snap" to a tick mark.
  719.                 This means that the value will always be 12*tick mark.
  720.  
  721.                 To avoid the "snap" behavior, use varCode 4.
  722.                         
  723. 3D Buttons        standard use of all fields, but with an 
  724.                 additional variation code for "Tog" buttons.
  725.                 
  726. Progress Bar    standard use of all fields.
  727.  
  728.                 Control cannot be disabled.
  729.  
  730. Tab Panel        min        = true height of the control. 
  731.                 max        = number of tabs
  732.                 value    = "active" tab. Title is bold.
  733.                 title    = one per tab, separated by CR (0x0d)
  734.                 refCon    = LoWord = tabs per row (2 - 8) - default of 4
  735.                           HiWord = right margin - no tabs drawn in this area.
  736.                 
  737.                 Rect should be set to #rows * 16 pixels, just enough for 
  738.                 all rows of tabs.
  739.                 
  740.                 Control cannot be disabled.
  741.  
  742. --------------------------------------------------------------------------------
  743.  
  744. Using custom controls in a dialog
  745. =================================
  746.  
  747. To use custom controls in a dialog, it is important to understand the
  748. interaction between the Dialog Manager, Control Manager and resource
  749. definitions for dialogs.
  750.  
  751. Underlying all controls in a Macintosh window (dialog or other) is the Control
  752. Manager.  Fundamental to this is the Toolbox call to create a new control:
  753.  
  754. ControlHandle hCtl;
  755.  
  756. hCtl = NewControl(
  757.             theWindow,        // the window the control belongs to
  758.             *theRect,        // rectangle for control
  759.             title,            // title for control
  760.             visible,        // initially visible or not
  761.             initialValue,    // control value
  762.             min,            // minimum value
  763.             max,            // maximum value
  764.             ctrlType,        // 16*procID+variation code
  765.             refCon            // user specified value
  766.             );
  767.  
  768. ctrlType is an important value and an understanding of its use if key to the
  769. use of custom controls.  The procID is the resource id of a code resource of
  770. type 'CDEF'.  Built into the Macintosh system are 'CDEF' resources of id 0 and
  771. 1 (and others).  The 'CDEF' with procID=0 is used for push buttons, check boxes
  772. and radio buttons - with variation codes of 0, 1 and 2 respectively.
  773.  
  774. So, to create buttons in a window, you could use NewControl and specify:
  775.  
  776.                            = 16*procID+variation code
  777.                            --------------------------
  778. Push Button        : ctrlType = 16*0+0 = 0
  779. Check Box        : ctrlType = 16*0+1 = 1
  780. Radio Button    : ctrlType = 16*0+2 = 2 
  781.  
  782. A special variation code of useWindFont (8) can be used with many controls to
  783. change the font of the control.
  784.  
  785. So, to use a custom control, you simply specify a procID of something other
  786. than 0.  If you want to substitute a custom control (like the 3D Button CDEF)
  787. for the default CDEF id=0, include a CDEF with id=0 in your application's
  788. resource fork.  This was done in the demo program (and in the xDEF.rsrc file).
  789.  
  790. Items in a dialog are specified in resource description files (.r files) using
  791. a syntax unique to your resource compiler.  A dialog resource is composed of a
  792. 'DLOG' resource and a corresponding 'DITL' resource. The 'DLOG' resource
  793. defines the dialog itself, while the 'DITL' resource  defines the item list for
  794. the dialog.  A typical item description in a 'DITL' source file might be:
  795.  
  796. resource 'DITL' (128) {
  797. /*    Control Rect,            ctrlType,     flag,        title            */
  798. /*    ---------------------    -----------    ---------    --------------- */
  799.     {249, 396, 269, 455},    Button         { enabled, "OK"             },
  800.     {249, 324, 269, 383},    Button          { enabled, "Cancel"            },
  801.     {52, 22, 68, 142},        CheckBox     { enabled, "Check box"        },
  802.     {76, 22, 92, 142},        RadioButton { enabled, "Radio button"    }
  803. };
  804.  
  805. For some standard controls (push buttons, radio buttons etc.), there are
  806. special 'DITL' definitions, as shown above.  The Dialog Manager reads the
  807. information in the 'DITL' resource, fills in some default values and calls
  808. NewControl().  (The 'enable' flag is not really a parameter to NewControl(),
  809. but sets the contrlHilite field in the control record.)
  810.  
  811. This means that you don't have to fill in the entire parameter list for
  812. NewControl() to have a control in a dialog - for the standard controls.
  813.  
  814. If you want to use the useWindFont variation code or a custom control in a
  815. dialog, there is some extra work to do…  You must define a special type of
  816. 'DITL' item, "Control" instead of "Button" etc. and then you must provide a
  817. matching resource of type 'CNTL'.  The Dialog Manager will recognize this type
  818. of 'DITL' item and read the 'CNTL' resource to get some of the parameters it
  819. will use in the call to NewControl().
  820.  
  821. The 'CNTL' resource contains fields for all of the parameters needed by
  822. NewControl().  In the example below, the DITL is changed to add the useWindFont
  823. variation to the items shown above, the resource  description would look like:
  824.  
  825. resource 'DITL' (128) {
  826. /*    Control Rect,            ctrlType,     flag,        'CNTL' id        */
  827. /*    ---------------------    -----------    ---------    --------------- */
  828.     {249, 396, 269, 455},    Control         { enabled,        128         },
  829.     {249, 324, 269, 383},    Control     { enabled,        129            },
  830.     {52, 22, 68, 142},        Control     { enabled,        130            },
  831.     {72, 22, 88, 142},        Control        { enabled,        131            }
  832. };
  833.  
  834. /*    Control Rect    initValue    visFlag        max    min    ctrlType    refCon    Title */
  835.  
  836. resource 'CNTL' (128, purgeable) {
  837.     {52, 22, 68, 142},        0,    visible,    1,    0,    16*0+8,        0,        "OK"
  838. };
  839. resource 'CNTL' (130, purgeable) {
  840.     {52, 22, 68, 142},        0,    visible,    1,    0,    16*0+8,        0,        "Cancel"
  841. };
  842. resource 'CNTL' (130, purgeable) {
  843.     {52, 22, 68, 142},        0,    visible,    1,    0,    16*0+1+8,    0,        "Check box"
  844. };
  845. resource 'CNTL' (131, purgeable) {
  846.     {72, 22, 88, 142},        0,    visible,    1,    0,    16*0+2+8,    0,        "Radio button"
  847. };
  848.  
  849. ** IMPORTANT **
  850.  
  851.     There are TWO rectangle definitions here - one in the 'DITL' and 
  852.     one in the 'CNTL'.  If they don't match, your custom control may
  853.     not draw, or it will flicker and seem to move when you first
  854.     show the dialog.  Also, clicks in the DITL rect may not be 
  855.     recognized by the Control when its rect is different. 
  856.     
  857.     Make sure the rects match.
  858.  
  859. If you use a resource editor instead of .r files & a resource compiler, you can
  860. define the 'DITL' and matching 'CNTL' resources directly. Resorcerer does a
  861. fine job at this.  ResEdit is a bit more difficult to use.
  862.  
  863. ResEdit does not keep the 2 rectangles in sync, if you drag a 'DITL' item
  864. around, the corresponding 'CNTL' is not updated.
  865.  
  866. To use ResEdit, open the 'DITL' window and define a new item of type "Control"
  867. from the floating palette.  Double click on the new item and fill in the
  868. resource id and rectangle information.  Move this window aside, but so that you
  869. can still see the rect info.
  870.  
  871. Now, hold down the command+option keys and double click on the item in the
  872. 'DITL' window.  This brings up the 'CNTL' window where you  can fill in the
  873. info for the 'CNTL' resource - fill in the "Bounds Rect" (top, left, bottom,
  874. right) item to match the rect in the 'DITL' window.
  875.  
  876.  
  877. --------------------------------------------------------------------------------
  878. Using custom controls in a normal window
  879. ========================================
  880.  
  881. In some ways, it is easier to use a control in a normal window than in a dialog.
  882. BUT, you have to do mouseDown event processing since the Dialog Manager is not
  883. doing it for you.
  884.  
  885. This is simple and identical to handling scroll bars or buttons in a window.  Just
  886. call FindControl to determine where & if the mouse was clicked in a control, then
  887. call TrackControl.  The code is nothing special, it looks like this:
  888.  
  889.             mousePt = theEvent->where;
  890.             GlobalToLocal(&mousePt);
  891.             partCode = FindControl(mousePt, theDialog, &controlHdl);
  892.             if(partCode && controlHdl) {
  893.                 TrackControl(cHdl, mousePt,  (ProcPtr)myTrack);
  894.             }
  895.             
  896. The only special things about these controls have to do with the last parameter to
  897. TrackControl - the actionProc.  Normally, you can simply take the default
  898. and pass nil as the last parameter.  See demoWind.c for some examples.
  899.  
  900. Exceptions are:
  901.  
  902. Popup Menu
  903. ----------
  904.     You must pass (ProcPtr)-1 to tell the CDEF to "autoTrack".
  905.  
  906. Spinner
  907. -------
  908.     You may define an actionProc which will be called when the mouse is
  909.     clicked in an arrow.  Unlike a scrollBar, the Spinner CDEF will update
  910.     its control value.  So in your action proc, you can call GetCtlValue to
  911.     obtain the current control value and do something with it (like stuff it
  912.     in an edit text record or display it).
  913.     
  914. Sliders
  915. -------
  916.     Sliders don't really need an actionProc, you can call TrackControl with
  917.     a nil actionProc and the slider will work just fine.
  918.     
  919.     If you want to implement a "live" display of the value of a slider control,
  920.     you simply define an actionProc, but use SetCtlAction to tell the control
  921.     to call it as the "thumb" of the slider is being dragged. (You still need
  922.     to call TrackControl though, or the control will not respond to clicks
  923.     in the scale portion of the control).
  924.     
  925.     In your actionProc, you can then call GetCtlValue to obtain the control
  926.     value and display it.
  927.     
  928. For the rest of the CDEFs, simply call TrackControl with a nil action proc 
  929. (unless you want to extract the control value and do something with it each
  930. time the mouse is clicked in the control - then you must define an actionProc).
  931.  
  932. --------------------------------------------------------------------------------
  933. Colorizing Controls & Dialogs
  934. --------------------------------------------------------------------------------
  935.  
  936. The key to having a colored dialog is to include a 'dctb' (or 'actb' for Alerts)
  937. with the same ID as the 'DLOG' or 'ALRT' resource.
  938.  
  939. For controls, there is a similar resource, a 'cctb'.  Either create 'cctb'
  940. resources for each 'CNTL' resource, or to color ALL controls in an application,
  941. create a 'cctb' with ID=0.
  942.  
  943. For the controls that have a "3D" variant, make sure you define the
  944. cTingeLight and cTingeDark colors in your 'cctb' or you won't get a nice
  945. looking control.
  946.  
  947. See demoDialog.r for examples.
  948.  
  949. --------------------------------------------------------------------------------
  950. Changing the font in a Dialog
  951. --------------------------------------------------------------------------------
  952.  
  953. Before showing your dialog (but after creating it), simple calls to:
  954.  
  955.     TextFont(geneva) and
  956.     TextSize(9)
  957.  
  958. will change the dialog font to Geneva 9.  This WILL NOT WORK if you have an
  959. edit text item in the dialog or if you forget to specify the useWindFont
  960. variation for your controls.
  961.  
  962. The best way to change the font for an edit item is to use 'ictb' resources, but
  963. these are a pain.  Only Resorcerer does this well, Rez and ResEdit don't
  964. support 'ictb' resources.
  965.  
  966. See demoDialog.c for a crude hack that seems to work.
  967.  
  968. --------------------------------------------------------------------------------
  969. Special PopUp menu notes
  970. --------------------------------------------------------------------------------
  971.  
  972. To start, the documentation in Inside Mac VI on the Apple popup menu CDEF
  973. is wrong in one detail.
  974.  
  975. There is no support for "popupRightJust" as shown in figure xxx showing a
  976. title to the right of the menu.  Instead, titles are always shown to the
  977. left, but can be left, center or right justified to the left of the menu.
  978.  
  979. This justification is done in a "title rect" that extends from the left
  980. of the control rect for as many pixels as you specify for "title width"
  981. in the controlMax field of the control template.
  982.  
  983. See the "Popup Menus" tab in the demoCDEF program to see how this works.
  984.  
  985. A goal in writing this CDEF was to duplicate the Apple CDEF 63, but with
  986. one that would behave the same under System 6 and System 7 and correctly
  987. work with colored menus or on a colored background.  The demoCDEF program
  988. has a dialog that shows both CDEFs side by side.
  989.  
  990. I came close to calling this CDEF "yapum" (Yet Another Popup Menu) since
  991. many have posted similar code.  I never found one that did exactly what
  992. I wanted (duplicate the behavior of the standard Apple CDEF), so I wrote
  993. this one.  Thanks to the other writers of popup CDEFs, I learned things
  994. from your code.
  995.  
  996. A major pain in writing this CDEF was insuring that the drawing of the
  997. popup when "at rest" (which is done by the CDEF) - matched EXACTLY, the
  998. drawing done by the Menu Manager when the menu is "popped up".  Without
  999. this, the menu appears jerky as things shift when you click in the control.
  1000. So, a goal in writing this popup CDEF was to duplicate the drawing done
  1001. by the standard MDEF as closely as possible.
  1002.  
  1003. I didn't get the drawing exactly the same in all cases.  Some oddball font
  1004. and size combinations may be off by a pixel or two.  Also, this control has
  1005. a slightly different manner of drawing the "popup symbol" and thus may be
  1006. a bit wider than the Apple CDEF 63 in a few cases.  It does match exactly
  1007. for Chicago 12 fonts.  I also deliberately centered the control title for
  1008. Iconic menus rather than the Apple approach of putting the title along the
  1009. top edge.  IMHO, centered looks better - it is lined up with the menu item
  1010. text.
  1011.  
  1012. As far as I know, you can use this CDEF with exactly the same parameters as
  1013. the Apple CDEF 63 and get the same results.  (I even went as far as pasting
  1014. it into my System and trying out a few apps and CommTools - it worked in
  1015. most cases.)
  1016.  
  1017. I don't recommend doing this though - Standard File was pretty much useless.
  1018. There must be some special hooks in the Apple CDEF for the Folder/Disk/Desktop
  1019. popup in Standard file.
  1020.  
  1021. A minor difference is variation code 2 - this CDEF uses this for a 3D 
  1022. embossed title while the System 6 CDEF uses 2 to mean "use Color QD" and 
  1023. System 7 ignores it.
  1024.  
  1025. I have deliberately NOT implemented 1 "feature".  This CDEF will not draw
  1026. command-keys.  IMHO, popups should not have command key equivalents and
  1027. there is a conflict when drawing - the menu manager will draw the command
  1028. key equivalent where the popup must draw the "popup symbol".  Apple's CDEF
  1029. shifts the command key to left, but then when the menu is popped up, they
  1030. shift to the right.  I find this distracting.
  1031.  
  1032. Two oddities that I have noticed are :
  1033.  
  1034. 1). Because of the AppendDITL calls (I think), menus with icons draw the
  1035. icons before drawing the popup frame.  Apple's CDEF does this too, I suspect
  1036. that it is a GrafPort problem but haven't really investigated.
  1037.  
  1038. 2). If you want an menu with Icons only, no text, you have to supply a space
  1039. as an item string or the standard MDEF ignores the menu.
  1040.  
  1041. Enhancements
  1042. ============
  1043.  
  1044. The popup CDEF in this package has several enhancements to the Apple CDEF.
  1045. These extensions are NOT backward compatible with the Apple CDEF!
  1046.  
  1047. You can see all of these extensions in the demoCDEF program on the 
  1048. "Popup Extensions" tab.
  1049.  
  1050. NOTE: earlier versions of this CDEF used a value of -1 in the contrlMax
  1051.         field to indicate "popupSymbolOnly".  THIS HAS BEEN CHANGED!
  1052.         
  1053. 1). It will handle "dynamic" menus created via NewMenu() as long as you
  1054. call InsertMenu() to add the menu to the menu list.
  1055.  
  1056. 2). Variation code 2 can be used for an embossed title as with the other
  1057. CDEFs in this package.
  1058.  
  1059. 3). There are several additional variants, all created via "pseudo variation
  1060. codes" which can be combined with the control Max value - which is normally 
  1061. used to specify the width of the title for a popup menu. 
  1062.  
  1063. Header file jimsCDEF.h has definitions for theses extensions.
  1064.  
  1065.     The first 3 are additive and can be combined with any other
  1066.     "pseudo variation code".
  1067.     
  1068.     1. No item marks (popupNoMark)
  1069.     
  1070.         Calling program can use SetItemMark() to set a mark if needed.
  1071.         One use of this would be to create a popup similar to the one
  1072.         used in Standard file dialogs.
  1073.     
  1074.     2. Black symbol (popupBlackSymbol)
  1075.     
  1076.         Default behavior with colored menus is to draw the popup symbol
  1077.         in the item text color. If you always want black symbols, add
  1078.         this "variation code" to controlMax.
  1079.     
  1080.     3. Inset 3D popup (popupInsetFrame)
  1081.     
  1082.         While working on the demoCDEF program, I realized that 3D dialogs
  1083.         (as used in the demo program) and popup menus look somewhat odd
  1084.         together.  The standard, drop-shadowed frame of a popup has the
  1085.         effect of "raising" the popup above the plane of the 3D dialog.
  1086.         
  1087.         So, I added another pseudo variation code to draw the popup menu
  1088.         as an "inset box" - a 3D effect that has the result of placing
  1089.         the popup below the plane of the dialog.  This only works if the
  1090.         dialog background color is non-white.  This effect was lost if the
  1091.         menu background color was white as well, so I chose to use the color
  1092.         of the current grafPort as the background color for the menu (in the
  1093.         case of the demo program, red=green=blue=0xCCCC).
  1094.         
  1095.         Of course, when the menu is "popped", the standard MDEF takes over
  1096.         drawing and the standard menu & drop shadow appear.
  1097.         
  1098.     The following are NOT additive with each other.  If added together,
  1099.     the results are undefined.
  1100.     
  1101.     4. "Symbol" only popups (popupSymbolOnly)
  1102.     
  1103.         For "type in" popups often used for Font size selection in
  1104.         conjunction with edit text items in dialogs. Additional code
  1105.         is needed to implement this, see the demoCDEF program source.
  1106.     
  1107.     5. Popups with no "Symbol" (popupNoSymbol)
  1108.     
  1109.         No downward pointing triangle is drawn, as in the System 6
  1110.         version of CDEF 63.
  1111.     
  1112.     6. Popups with icons only (popupIconOnly)
  1113.     
  1114.         This results in a "popup Icon button" effect since only a
  1115.         framed icon (of any size or type) is drawn.  Item text and
  1116.         the popup symbol are not drawn. 
  1117.         Set the control rect to 5 pixels more than the largest icon.
  1118.     
  1119.     7. Popups with centered text (popupCenterText)
  1120.     
  1121.         This results in a "popup text button" effect since the menu
  1122.         item text is drawn, centered in the control rect.
  1123.  
  1124. --------------------------------------------------------------------------------
  1125. About "TogButtons" 
  1126. --------------------------------------------------------------------------------
  1127. In early November 1991, I ran across an article in the October 1991 "Apple
  1128. Direct" by Bruce Tognazzini - Apple's human interface guru.   Each month Tog
  1129. would write a column dealing with HI issues.  The article that caught my eye
  1130. back then was titled "Case Study: One or more Buttons".  
  1131.  
  1132. I don't think that I can legally include Tog's article with this bit of code,
  1133. but you can find it on many of the Apple Developer CD's in the 
  1134.  
  1135. Periodicals:Apple Direct:Apple Direct Oct '91:Tog folder.  
  1136.  
  1137. It also is in his book "Tog on Interface" as chapter 36.
  1138.  
  1139. To summarize, Tog wrote about the design and usability testing of a new 
  1140. interface element that he called "One or more Buttons" - essentially a control
  1141. that was part Checkbox and part Radio button.  A group of Checkboxes can all be
  1142. "Off" and a group of Radio buttons can only have one "On" value.  What was
  1143. needed was a group that MUST have ONE "On" control but could have many "On"
  1144. controls - a "One or more Button".
  1145.  
  1146. Tog's design for what I call "Tog Buttons" is a cross between a Radio button
  1147. and a Checkbox.  The control is a diamond (a Checkbox rotated 90 degrees) with
  1148. a diamond shaped indicator (like the  circular indicator in a Radio button). 
  1149. The behavior is also a cross between the two other controls.  If only one
  1150. control is ON, then clicking on it turns that control OFF and turns on an
  1151. adjacent control (just like a pair of radio buttons), if one or more of the
  1152. controls is ON, then others can be toggled (just like a checkbox).
  1153.  
  1154. Another twist on the behavior is that if only one control is ON, a click on
  1155. that control will turn if OFF, and turn on the one just above (or to the left
  1156. of) it.  When the first (or last) control  is reached, the direction reverses,
  1157. turning on the one just below  (or to the right).  Tog likened this behavior to
  1158. that of a drop of  mercury when you press on it with a finger (but without the
  1159. toxicity!).
  1160.  
  1161. The behavior is such that with a single ON button, clicking on just that
  1162. button, causes it to "jump" up (or leftward).  If you keep chasing the single
  1163. ON button, it will keep "jumping" up until it must reverse direction and start
  1164. "jumping" down.  Unless you are "chasing" a button like this, when only one
  1165. button is ON, the default behavior is to jump UP (or to the left).  To see
  1166. this, try the cdefDemo program and you will see what I mean.   
  1167.  
  1168. For some reason, this appealed to me as an interesting project and I spent a
  1169. fun afternoon implementing Tog's idea.  I ended up creating a CDEF to implement
  1170. the control described by Tog and a couple of routines in C to support the
  1171. desired behavior of "Tog Buttons".
  1172.  
  1173. --------------------------------------------------------------------------------
  1174. How to use a Tog Button in a dialog
  1175. ===================================
  1176.  
  1177. Obviously, using a Tog Button is only needed if you have a situation that has a
  1178. group of items that requires "One or Many" values.  An example might be a
  1179. search :
  1180.  
  1181.    - Search -----------------
  1182.   |                          |
  1183.   | <•> C files (.c)         |
  1184.   | < > Include files (.h)   |
  1185.   | < > Resource files (.r)  |
  1186.   |                          |
  1187.    --------------------------
  1188.    
  1189. The file cdefDemo.c shows how to use "Tog Buttons", but here is a brief list.
  1190.  
  1191. 1. Include the files TogLib.c/TogLib.h in your project.
  1192.  
  1193. 2. Define the group of "Tog Buttons" in your dialog resource.
  1194.  
  1195. 3. DITL item numbers MUST be successively numbered for each group of "Tog
  1196.    Buttons".  This is IMPORTANT!
  1197.  
  1198. 4. After calling GetNewDialog, but before calling ModalDialog,  call
  1199.    initTogButtons() for each group of "Tog Buttons".
  1200.  
  1201. 5. When a "Tog Button" is clicked, call setTogButtons() for that group of "Tog
  1202.    Buttons".
  1203.  
  1204. 6. When a non-Tog Button control is clicked, do whatever is needed, then call
  1205.    resetTogButtons() for each group of  "Tog Buttons".  This step simply insures
  1206.    that the next click on a "Tog Button" will "go up".
  1207.  
  1208. 7. Use regular calls to GetDItem() and GetCtlValue() to retrieve the control
  1209.    values for "Tog Buttons".
  1210.  
  1211. The TogLib routines are the key to maintaining consistent behavior of the "Tog
  1212. Buttons".  TogLib.h has a short description of each routine.
  1213.  
  1214. --------------------------------------------------------------------------------
  1215. About Tab Panels
  1216. --------------------------------------------------------------------------------
  1217. Tab panels are what I call dialogs that use the TabPanel CDEF in this package.
  1218.  
  1219. The CDEF is modeled after what I think is Microsoft's "Tabbed dialog" interface
  1220. design.  I think that this is being used in the new Mac versions of Word &
  1221. Excel, but I haven't seen them yet.
  1222.  
  1223. It could be used as an alternative to the common Mac approach of multi-panel
  1224. dialogs that use a list of Icons to switch among several panels.
  1225.  
  1226. This is doubtless a controversial interface element - even more so on the Mac. 
  1227. I don't condone it's use, I simply wanted to see if I could write a control
  1228. like this.
  1229.  
  1230. Think long and hard before you use this on the Mac - it may be rather foreign
  1231. to Mac users and will take some thought.  One of the biggest difficulties is
  1232. "Where do the OK & Cancel buttons go?" and "What does a click on a tab mean?" -
  1233. should changes be applied immediately, or wait for an OK on the dialog?
  1234.  
  1235. If OK & Cancel are inside the "Tab" control, do you have to click on OK before
  1236. changing tabs?  How do you exit the dialog?  Do you then need a "Done" button".
  1237. Is a click on a tab the same as OK? and so on…
  1238.  
  1239. If the OK and Cancel buttons are outside the "Tab" control, then do you need an
  1240. "Apply" button that must be clicked  or you loose changes if you switch panels
  1241. by clicking on a  new tab?  Or is a click on a tab is that an implied
  1242. acceptance of changes that will take effect when you click "OK"?
  1243.  
  1244. There is some subtle but important stuff here. Think about it!
  1245.  
  1246. Using the Tab Panel CDEF
  1247. ------------------------
  1248.  
  1249. You can specify from 1 to 40 tabs with this control (one would be silly and
  1250. 40 is overkill).  Tabs are presented with 4 per row by default, each tab is 
  1251. 1/4 of the width of the control.  "Tabs per row" may be between 2 and 8.
  1252.  
  1253. If you specify a tab count that is not a multiple of "tabs per row", the 
  1254. remaining tabs  will be wider than the others so that the entire control width 
  1255. is occupied.  This looked better (IMHO) than having an empty space or a "dead"
  1256. tab.
  1257.  
  1258. The control max value indicates the total number of tabs. 
  1259.  
  1260. The control title should contain a title for each tab, separated by a CR.  
  1261.  
  1262. If you want to change the default number of tabs per row, put a value
  1263. from 2 to 8 in the LoWord of the refCon field.
  1264.  
  1265. If you want a "notch" on the right side with no tabs, put a "notch" value 
  1266. in the HiWord of the refCon field.  
  1267.  
  1268. The control rect height should be set to #rows * height of 1 tab.  Then set 
  1269. the REAL height for the entire panel in the contrlMin field of the control
  1270. template.  
  1271.  
  1272. ** NOTE ** Be particularly careful to match up the DITL item rect and CNTL
  1273. rects - if these are not the same, you may end up with a "dead" row of tabs
  1274. that will not respond to a click.
  1275.  
  1276. The height of each row of tabs is calculated as : controlHeight/rows. 16 pixels
  1277. per row is a good size.  So, if you need 2 rows of tabs, set the control rect 
  1278. to be 32 high.
  1279.  
  1280. By default, this control will use a Geneva 9 font, with the "active" tab drawn
  1281. as Bold.  If you use the useWindFont variation code of 8, it will use the current
  1282. font. A variation code of 1 will use the System font at all times, underlined 
  1283. instead of bold (IMHO, this looks better than bold Chicago 12).
  1284.  
  1285. A variation code of 2 will force a single row of tabs, with as many tabs as 
  1286. specified by controlMax, each as wide as controlWidth/# tabs.
  1287.     
  1288. If the background is not white, the control will draw as a "3D" control.
  1289.     
  1290. Please note that the control cannot be disabled, nor can a single tab be disabled.
  1291.  
  1292. If you have a situation where an entire panel should be disabled, disable each
  1293. of the controls on the panel.
  1294.  
  1295. Changing the controls as you switch from tab to tab can be done in several ways.
  1296. One is to use the AppendDITL and ShortenDITL found in System 7 - this is the 
  1297. approach used in the demoCDEF program and in support routines found in
  1298. panelAssist.c. That file has 3 routines that might be handy - one to swap panels,
  1299. one to implement command+number keys as an alternative to clicking on a tab and
  1300. another to implement command+Tab or control+Tab to cycle through the tabs.
  1301.  
  1302. If you need to use the TabPanel CDEF with System 6, a series of MoveControl or 
  1303. Hide/ShowControl calls would probably do the trick.
  1304.  
  1305. The files demoDialog.c and tabDemo.c show how to use a "Tab Panel".
  1306.  
  1307. File demoDialog.c has routines that preserve the settings of each 
  1308. control on each panel.
  1309.  
  1310. File tabDemo.c is a "bare bones" example of how to work with the CDEF.
  1311.  
  1312. Briefly, to use the TabPanel CDEF:
  1313.  
  1314. 1. Include the files panelAssist.c/panelAssist.h in your project.
  1315.  
  1316. 2. Define a DLOG resource and DITL that contains just 3 controls "OK",
  1317.    "Cancel" and the TabPanel control as items 1-3.  
  1318.  
  1319. 3. Set the contrlMax value to the number of tabs you want and provide
  1320.    a title for each in the control title.
  1321.    
  1322. 4. Define a 'DITL' resource for each tab.  Number them successively,
  1323.    starting with the previous DITL+1.
  1324.  
  1325. 5. Study the code in demoDialog.c.  That example places the OK & Cancel buttons
  1326.    outside the panel and saves all control values to a temp area before switching
  1327.    to another panel.
  1328.  
  1329. 6. When Modal dialog informs your program that a Tab was clicked (itemHit is
  1330. equal to the tabPanel DITL item), do the following:
  1331.     
  1332.         - get the value of the tab control.
  1333.         - save the values of other controls on the current panel.
  1334.         - call panelSwap with the new tab value to change panels.
  1335.             (this uses CountDITL, ShortenDITL and AppendDITL)
  1336.         - restore the values of the controls on the new panel.
  1337.         
  1338. 7. If you want to use command+number keys to switch panels, call panelCmdKey()
  1339. from your dialog filter routine whenever a keyboard event occurs with the
  1340. command key down - obviously, this is only good for 10 or fewer tabs.  
  1341.  
  1342. To use command+Tab or control+Tab to rotate through tab panels, call 
  1343. panelCmdTab() when the control or command keys are pressed.
  1344.  
  1345. --------------------------------------------------------------------------------
  1346. Revision History:
  1347. --------------------------------------------------------------------------------
  1348. v1.3    November 1994
  1349.                     - first release with full source
  1350.                     - will compile under Think 6 or Think 7
  1351.                     - compiled without MacsBug names to decrease size.
  1352.                     - tightened up code in cdef3D, had some bogus code
  1353.                       that was not needed - sloppy copy 'n' paste.
  1354.                       
  1355.                     - added to demoCDEF program to demonstrate use of
  1356.                       these CDEFs in a window as well as in a dialog
  1357.                       and to add a couple of simple TabPanel demos.
  1358.         GroupBox
  1359.         --------            
  1360.                     - GroupBox has a new variation 4, "insetBox" to draw
  1361.                       a simple box with the bottom/right edges in white
  1362.                       and top/left edges in a gray shade taken from
  1363.                       cFrameColor and GetGray().
  1364.         Spinner
  1365.         -------        - added new variation code, "horizArrows" to create
  1366.                       arrows that point left/right instead of up/down.
  1367.         TabPanel
  1368.         --------    - LoWord of refCon can specify from 2 to 8 tabs per
  1369.                       row.  Default is 4 per row.  HiWord of refCon is
  1370.                       used as a 'notch' in the right corner.
  1371.                       
  1372.             * NOTE *  This is a change in the use of the refCon from
  1373.                       previous versions of this control.          
  1374.         Popup Menu
  1375.         ----------
  1376.                     - Major enhancements to popup Menu CDEF
  1377.                     
  1378.                         o Now should be completely "plug compatible" with
  1379.                           Apple's CDEF 63 - with one exception - it will
  1380.                           not draw command-key equivalents.
  1381.                           
  1382.                         o Supports "dynamic" menus created via NewMenu() as
  1383.                           long as they have been inserted into the menu
  1384.                           list with InsertMenu()
  1385.                           
  1386.                         o Supports ICONS, reduced ICONS, SICN's and cicn's
  1387.                         
  1388.                         o Supports styled text titles.
  1389.                     
  1390.                         o Added 7 enhancements over CDEF 63, all triggered
  1391.                           by adding a "pseudo variation code" to the title
  1392.                           width value in the controlMax field.
  1393.                           
  1394.                           popupNoMark      : Don't use a checkmark on current item.
  1395.                           popupBlackSymbol: Always draw symbol in black.
  1396.                           popupInsetFrame : Draws an inset popup frame.
  1397.                           
  1398.                           popupSymbolOnly : Draw popup symbol for "type-in menus"
  1399.                           popupNoSymbol      : Don't draw popup symbol at all.
  1400.                           popupCenterText : Don't draw popup symbol, don't expand 
  1401.                                               control width to that of the menu and
  1402.                                               center item text in control rect.
  1403.                           popupIconOnly      : Draw item Icon in a framed box.
  1404.                           
  1405.                         o popupNoMark, popupBlackSymbol and popupInsetFrame can 
  1406.                           be combined with others, but combinations of the last 
  1407.                           4 are undefined.
  1408.                           
  1409. v1.2    September 1994
  1410.  
  1411.                     - removed bogus UpdtDialog() call from demoCDEF.c - could
  1412.                       cause a crash and wasn't needed.
  1413.                     - minor fix to dimText.c.
  1414.                     - fixed multiple monitor color problems in CDEFs that
  1415.                       do not use offScreen drawing (3D Buttons, Popup, 
  1416.                       Tab Panel, Progress Bars & Group Box).
  1417.                     - reworked some of the common routines for CDEFs in
  1418.                       source folder "CDEF Common".
  1419.                     - finally got around to checking the controls in a window
  1420.                       as opposed to a dialog.  Lots of minor tweaks to make
  1421.                       things work correctly with FindControl & TrackControl.
  1422.                       Details follow.
  1423.                     - many enhancements to the demoCDEF program to show:
  1424.                         : disabled Group Boxes
  1425.                         : Fractional increment in Spinner controls
  1426.                         : "Live" display of control values for Sliders
  1427.                         : Reset of DateTime controls to current time.
  1428.                         : Linking of a Spinner control to Progress bar.        
  1429.         
  1430.         Spinner
  1431.         -------            
  1432.         
  1433.     ** MAJOR CHANGE **
  1434.     
  1435.                     - the meaning of the refCon field has changed:
  1436.                             LOWORD is the increment value to use
  1437.                             HIWORD is the DITL item number to update 
  1438.                             
  1439.                       The refCon value is only checked when the control is first
  1440.                       initialized.  The HIWORD is only honored if the controlOwner
  1441.                       is a dialog window.
  1442.                       
  1443.                     - Spinner control has a new variation to get "3D" arrows.
  1444.                       Use varCode 2 for this.  3D arrows are colored as are
  1445.                       system scroll bars with cTingeLight & cTingeDark.
  1446.                       
  1447.                     - Spinner control now behaves correctly with TrackControl.  
  1448.                       Part codes returned are :
  1449.                           2 = decrease value
  1450.                         3 = increase value
  1451.                         
  1452.                     - it is now possible to have a spinner control that adjusts
  1453.                       by a fractional value.  This requires some special code in
  1454.                       your program (after all, the contrlValue field is a short).
  1455.                       See demoDialog.c for an example.
  1456.                       
  1457.                       To do this, a struct is provided to let you store userData
  1458.                       in the control's internal contrlData field - which is used
  1459.                       by the control.  See jimsCDEF.h for the struct.
  1460.         Tab Panel
  1461.         ---------              
  1462.                     - Tab Panel improved to handle multiple rows of tabs.
  1463.                       It defaults to 4 tabs per row, with a maximum of 5
  1464.                       rows.  Variation code 2 added to force a single row.
  1465.                       Variation code 1 will force System font.
  1466.                     - added panelCmdTab() to panelAssist.c to allow cmd-Tab or
  1467.                       cntl-Tab to cycle through the tabs.
  1468.         Sliders
  1469.         -------                    
  1470.                     - Slider controls now behave correctly with Find/Track Control
  1471.                       and will call an actionProc from SetCtlAction() if set.
  1472.                       Part codes returned are :
  1473.                           1 = "thumb" adjusted value
  1474.                           2 =  value was decreased
  1475.                           3 =  value was increased
  1476.                           
  1477.                     - Slider controls : change in variation codes :
  1478.                             1 is now for "unfilled scale"
  1479.                             2 is now for "3D" effect
  1480.  
  1481.         Date & Time
  1482.         -----------
  1483.                     - DateTime control values were changed to indicate what
  1484.                       digits are currently highlighted.  FindControl part codes 
  1485.                       returned are:
  1486.                           2  - Hours 
  1487.                           3  - Minutes 
  1488.                           4  - AM/PM
  1489.                           5  - TimeUp        (never as control value)
  1490.                           6  - TimeDown    (never as control value)
  1491.                           
  1492.                           7  - date 1 (per control panel)
  1493.                           8  - date 2
  1494.                           9  - date 3
  1495.                           10 - DateUp        (never as control value)
  1496.                           11 - DateDown    (never as control value)
  1497.                     
  1498.                     - DateTime control now has 2 "pseudo variation codes":
  1499.                         : if control Max is non-zero, 24 hour time is forced.
  1500.                         : if control Min is non-zero, use 3D effect for arrows
  1501.                           & text as with the Spinner control.
  1502.         Popup Menu
  1503.         ----------
  1504.                     - Popup Menu control now recognizes variation 2 for 3D
  1505.                       effects as in Group Boxes, Sliders and Spinner control.
  1506.                       
  1507.                     - as with Apple's CDEF 63, call TrackControl with the last
  1508.                       parameter set to -1 to use this control in a regular
  1509.                       window.
  1510.         Group Box
  1511.         ---------
  1512.                     - now will disable and draw in gray.
  1513.                     
  1514. --------------------------------------------------------------------------------
  1515.           
  1516. v1.1    August 1994    - added Tab Panel CDEF to collection (see description
  1517.                       above).
  1518.                     - all CDEFs use "embossed" text if used on a non-
  1519.                       white background.
  1520.                     - DateTime control now uses a title if supplied in
  1521.                       control template.
  1522.                     - PopUpMenu control draws color title per 'cctb' 
  1523.                       rather than 'mctb' and will "emboss" as with others.
  1524.                       When the menu is "popped", the title colors are the
  1525.                       same as the inverted menu item, rather than 'cctb'.
  1526.                       colors.  IMHO, this looks better.
  1527.                     - Fixed a PenSize problem with 3D Buttons in Alerts
  1528.                       with no 'actb' resource.
  1529.                     - slider controls corrected to use proper gray when
  1530.                       inactive.
  1531.                     - slider controls now respond to clicks in the scale
  1532.                       portion of the control.
  1533.                     - variation 1 (was gray thumb) in slider controls now
  1534.                       draws a "3D" version of the control.  Shadow color
  1535.                       is cTingeLight from 'cctb'.
  1536.                     - removed a MAJOR memory leak in the slider controls.
  1537.                     - Added a "barberpole" variation to the ProgressBar.
  1538.                     
  1539.                     - completely rewrote demo program to use the TabPanel
  1540.                       control.
  1541.                       
  1542. --------------------------------------------------------------------------------
  1543.  
  1544. v1.01    July 1994    - 3D Buttons now supports multi-line titles
  1545.                     - GroupBox uses Control Max instead of refCon for
  1546.                       true height of box (templates must be changed).
  1547.                     - both slider controls have a correction to tracking
  1548.                       logic when mouse is moved past end of slider. Now,
  1549.                       tracking will not resume until mouse is moved back
  1550.                       to the thumb.
  1551.         
  1552. --------------------------------------------------------------------------------
  1553.  
  1554. v1.0    June 1994    - first distribution
  1555.